memcpy関数とmemmove関数は、メモリ領域のデータを指定された長さだけコピーします。memcpy関数とmemmove関数の相違は、memcpy関数はコピー元の領域とコピー先の領域が重なってはいけないのに対して、memmove関数は重なっていてもよいということです。
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
*destはコピー先の先頭アドレスを指定します。
*srcはコピー元の先頭アドレスを指定します。
nはコピーする長さをバイト単位で指定します。
戻り値として、第1引数*destのアドレスを返します。
次の例題プログラムは、ファイル中の’&’、'<‘、’>’、’\’記号を、それぞれ’&’、’<’、’>’、’\’に置換して、表示します。
プログラム 例
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 1024 int main(int argc, char *argv[]) { FILE *fp; char buff[SIZE]; char *buff_ptr; char key[] = '&<>\\'; /* 置換対象文字 */ char *cnv_char[] = {'&', /* 置換文字 & */ '<', /* < */ '>', /* > */ '\'}; /* \ */ int key_index; if (argc != 2) { fprintf(stderr, '実行時引数が不当です\n'); exit(EXIT_FAILURE); } if ((fp = fopen(argv[1], 'r')) == NULL) { fprintf(stderr, '%sのオープンができませんでした\n', argv[1]); exit(EXIT_FAILURE); } while(fgets(buff, SIZE, fp) != NULL) { /* 置換対象文字数分だけ、繰り返す */ for (key_index = 0; key_index < strlen(key); ++key_index) { buff_ptr = buff; /* 入力した行の最後まで */ while (*buff_ptr != '\0') { /* 置換対象文字のチェック */ if (*buff_ptr == key[key_index]) { /* 置換文字を挿入できる分だけ文字列をずらす */ memmove(buff_ptr + strlen(cnv_char[key_index]), buff_ptr + 1, strlen(buff_ptr)); /* 置換文字を挿入 */ memcpy(buff_ptr, cnv_char[key_index], strlen(cnv_char[key_index])); buff_ptr += strlen(cnv_char[key_index]); } else { ++buff_ptr; } } } printf('%s', buff); } fclose(fp); return EXIT_SUCCESS; }
例の実行結果
$ cat temp.txt #include <stdio.h> int main() { printf('Hello World!!.\n'); return 0; } $ $ ./memcpy.exe temp.txt #include <stdio.h> int main() { printf('Hello World!!.\n'); return 0; } $